/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.component.gateway.dianlan.facade.enums;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import info.peigen.hotpot.common.core.enums.Messageable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.beetl.sql.annotation.entity.EnumValue;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <b>(DianlanTransStopDetail)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2022/9/2
 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
public enum DianlanTransStopDetail implements Messageable {
    /** 为了对抗 Alibaba Java Coding 而存在的注释 */
    Code_00("00", "无"),
    Code_40("40", "结束充电，APP 远程停止"),
    Code_41("41", "结束充电，SOC 达到 100%"),
    Code_42("42", "结束充电，充电电量满足设定条件"),
    Code_43("43", "结束充电，充电金额满足设定条件"),
    Code_44("44", "结束充电，充电时间满足设定条件"),
    Code_45("45", "结束充电，手动停止充电"),
    Code_46("46", "其他方式（预留）"),
    Code_47("47", "其他方式（预留）"),
    Code_48("48", "其他方式（预留）"),
    Code_49("49", "其他方式（预留）"),

    Code_4A("4A", "充电启动失败，充电桩控制系统故障(需要重启或自动恢复)"),
    Code_4B("4B", "充电启动失败，控制导引断开"),
    Code_4C("4C", "充电启动失败，断路器跳位"),
    Code_4D("4D", "充电启动失败，电表通信中断"),
    Code_4E("4E", "充电启动失败，余额不足"),
    Code_4F("4F", "充电启动失败，充电模块故障"),
    Code_50("50", "充电启动失败，急停开入"),
    Code_51("51", "充电启动失败，防雷器异常"),
    Code_52("52", "充电启动失败，BMS 未就绪"),
    Code_53("53", "充电启动失败，温度异常"),
    Code_54("54", "充电启动失败，电池反接故障"),
    Code_55("55", "充电启动失败，电子锁异常"),
    Code_56("56", "充电启动失败，合闸失败"),
    Code_57("57", "充电启动失败，绝缘异常"),
    Code_58("58", "预留"),
    Code_59("59", "充电启动失败，接收 BMS 握手报文 BHM 超时"),
    Code_5A("5A", "充电启动失败，接收 BMS 和车辆的辨识报文超时 BRM"),
    Code_5B("5B", "充电启动失败，接收电池充电参数报文超时 BCP"),
    Code_5C("5C", "充电启动失败，接收 BMS 完成充电准备报文超时 BRO AA"),
    Code_5D("5D", "充电启动失败，接收电池充电总状态报文超时 BCS"),
    Code_5E("5E", "充电启动失败，接收电池充电要求报文超时 BCL"),
    Code_5F("5F", "充电启动失败，接收电池状态信息报文超时 BSM"),
    Code_60("60", "充电启动失败，GB2015 电池在 BHM 阶段有电压不允许充电"),
    Code_61("61", "充电启动失败，GB2015 辨识阶段在 BRO_AA 时候电池实际电压与 BCP 报文电池电压差距大于 5%"),
    Code_62("62", "充电启动失败，B2015 充电机在预充电阶段从 BRO_AA 变成BRO_00 状态"),
    Code_63("63", "充电启动失败，接收主机配置报文超时"),
    Code_64("64", "充电启动失败，充电机未准备就绪,我们没有回 CRO AA，对应老国标"),
    Code_65("65", "（其他原因）预留"),
    Code_66("66", "（其他原因）预留"),
    Code_67("67", "（其他原因）预留"),
    Code_68("68", "（其他原因）预留"),
    Code_69("69", "（其他原因）预留"),

    Code_6A("6A", "充电异常中止，系统闭锁"),
    Code_6B("6B", "充电异常中止，导引断开"),
    Code_6C("6C", "充电异常中止，断路器跳位"),
    Code_6D("6D", "充电异常中止，电表通信中断"),
    Code_6E("6E", "充电异常中止，余额不足"),
    Code_6F("6F", "充电异常中止，交流保护动作"),
    Code_70("70", "充电异常中止，直流保护动作"),
    Code_71("71", "充电异常中止，充电模块故障"),
    Code_72("72", "充电异常中止，急停开入"),
    Code_73("73", "充电异常中止，防雷器异常"),
    Code_74("74", "充电异常中止，温度异常"),
    Code_75("75", "充电异常中止，输出异常"),
    Code_76("76", "充电异常中止，充电无流"),
    Code_77("77", "充电异常中止，电子锁异常"),
    Code_78("78", "预留"),
    Code_79("79", "充电异常中止，总充电电压异常"),
    Code_7A("7A", "充电异常中止，总充电电流异常"),
    Code_7B("7B", "充电异常中止，单体充电电压异常"),
    Code_7C("7C", "充电异常中止，电池组过温"),
    Code_7D("7D", "充电异常中止，最高单体充电电压异常"),
    Code_7E("7E", "充电异常中止，最高电池组过温"),
    Code_7F("7F", "充电异常中止，BMV 单体充电电压异常"),
    Code_80("80", "充电异常中止，BMT 电池组过温"),
    Code_81("81", "充电异常中止，电池状态异常停止充电"),
    Code_82("82", "充电异常中止，车辆发报文禁止充电"),
    Code_83("83", "充电异常中止，充电桩断电"),
    Code_84("84", "充电异常中止，接收电池充电总状态报文超时"),
    Code_85("85", "充电异常中止，接收电池充电要求报文超时"),
    Code_86("86", "充电异常中止，接收电池状态信息报文超时"),
    Code_87("87", "充电异常中止，接收 BMS 中止充电报文超时"),
    Code_88("88", "充电异常中止，接收 BMS 充电统计报文超时"),
    Code_89("89", "充电异常中止，接收对侧 CCS 报文超时"),
    Code_8A("8A", "（其他原因）预留"),
    Code_8B("8B", "（其他原因）预留"),
    Code_8C("8C", "（其他原因）预留"),
    Code_8D("8D", "（其他原因）预留"),
    Code_8E("8E", "（其他原因）预留"),
    Code_8F("8F", "（其他原因）预留"),

    Code_90("90", "未知原因停止"),

    /** 不晓得啷格回事 */
    UNKNOWN("--", "不晓得啷格回事");

    /** 枚举值 */
    @EnumValue
    String code;

    /** 枚举描述 */
    String message;


    /**
     * 通过枚举<code>code</code>获得枚举
     *
     * @param code 枚举值
     *
     * @return DianlanTransStopDetail
     */
    public static DianlanTransStopDetail getByCode(String code) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equals(code, innerEnum.code()))
                .findFirst().orElse(UNKNOWN);
    }

    /**
     * 通过枚举<code>name</code>获得枚举
     *
     * @param name 枚举名
     *
     * @return DianlanTransStopDetail
     */
    public static DianlanTransStopDetail getByName(String name) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equalsIgnoreCase(name, innerEnum.name()))
                .findFirst().orElse(UNKNOWN);
    }

    /**
     * 获取全部枚举
     *
     * @return List<DianlanTransStopDetail>
     */
    public static List<DianlanTransStopDetail> getAllEnum() {
        return Lists.newArrayList(values());
    }

    /**
     * 获取全部枚举值
     *
     * @return List<String>
     */
    public static List<String> getAllEnumCode() {
        return getAllEnum().stream().map(DianlanTransStopDetail::code).collect(Collectors.toList());
    }

    /**
     * 通过code获取msg
     *
     * @param code 枚举值
     *
     * @return String
     */
    public static String getMsgByCode(String code) {
        return getByCode(code).message();
    }

    /**
     * 获取枚举code
     *
     * @param innerEnum 枚举
     *
     * @return code
     */
    public static String getCode(DianlanTransStopDetail innerEnum) {
        return Optional.ofNullable(innerEnum).map(DianlanTransStopDetail::code).orElse(UNKNOWN.code());
    }

    /**
     * map
     *
     * @return Map
     */
    public static Map<String, String> maps() {
        return Stream.of(values()).collect(Collectors.toMap(DianlanTransStopDetail::code, DianlanTransStopDetail::message));
    }

    /**
     * 该方法是为了避免NPE，安全获取枚举中的字段值
     */
    public static <T> T safeGet(DianlanTransStopDetail enumValue, Function<DianlanTransStopDetail, T> mapper, T defaultValue) {
        return Objects.isNull(enumValue) ? defaultValue : mapper.apply(enumValue);
    }

    /**
     * 该方法是为了避免NPE，安全获取枚举中的字段值，默认返回值是null
     */
    public static <T> T safeGet(DianlanTransStopDetail enumValue, Function<DianlanTransStopDetail, T> mapper) {
        return safeGet(enumValue, mapper, null);
    }

    /**
     * 该方法是为了避免NPE，安全获取枚举中的code值，默认返回值是null
     */
    public static String safeGetCode(DianlanTransStopDetail enumValue) {
        return safeGet(enumValue, Messageable::code, null);
    }

    /**
     * 判断给定的枚举，是否在列表中
     *
     * @param values 列表
     *
     * @return Boolean
     */
    public boolean isInList(DianlanTransStopDetail... values) {
        for (DianlanTransStopDetail e : values) {
            if (this == e) {
                return true;
            }
        }
        return false;
    }

    /**
     * @return Returns the code.
     */
    @Override
    public String code() {
        return code;
    }

    /**
     * @return Returns the message.
     */
    @Override
    public String message() {
        return message;
    }
}